#!/usr/bin/env python
# encoding: utf-8
"""
usermodel.py

Created by AlanYang on 2011-06-04.
Copyright (c) 2011 __MyCompanyName__. All rights reserved.
"""
import redis
import cPickle
import hashlib
import pymongo

from flask import g
from mongomodel import MongoModel

from application import app
from apps.search.searchmodel import index

def login(uid,passwd):
    user = UserModel()
    return user.login(uid, passwd)

def changeuser(uid,user):
    return UserModel().changeuser(uid,**user)
    
@index(['nick'])
def setuser(user):
    print user
    return UserModel(**user).commit()

def changepasswd(uid,oldpasswd,newpasswd):
    return UserModel().changepasswd(uid, oldpasswd, newpasswd)

def getuser(uid):
    return UserModel().getuser(uid)

@app.signal_addquestion.connect
def adduserquestion(sender,**kv):
    uid = kv.pop('uid',None)
    qid = kv.pop('qid',None)
    if not uid or not qid:
        return False
    return UserModel().addquestion(uid, qid)

def getuserquestions(uid,skip=0,limit=10):
    qs = UserModel().getquestions(uid, skip, limit)
    return filter(lambda _q:not not _q,[getquestion(q) for q in qs])

@app.signal_addanswer.connect
def adduseranswer(sender,**kv):
    uid = kv.pop('uid',None)
    qid = kv.pop('qid',None)
    answer = kv.pop('answer',None)
    if not uid or not qid:
        return False
    return UserModel().addanswer(uid, qid, answer)

def getuseranswers(uid,skip=0,limit=10):
    ans = UserModel().getanswers(uid, skip, limit)
    return [app.signal_getquestion.send(__name__,qid=answer['qid'])[0][1] for answer in ans]

adduser = setuser

class UserModel(MongoModel):
    def __init__(self,**user):
        self.user = user
        if not getattr(g, 'mongo',None):
            g.mongo = pymongo.Connection(app.config['MONGO_HOST'],app.config['MONGO_PORT'])
        if not getattr(g, 'redis',None):
            g.redis = redis.Redis(app.config['REDIS_HOST'],app.config['REDIS_PORT'],db=app.config['DB_REDIS_USER'])
        MongoModel.__init__(self, g.mongo.freeasker.user, '_id', g.redis, app.config['DEFAULT_EXPIRE'])
        
    def __question_key__(self,uid):
        return '%s:%s:%s'%('user','question',uid)
    
    def __answer_key__(self,uid):
        return '%s:%s:%s'%('user','answer',uid)
        
    def __set_cache__(self, user):
#        user.pop('passwd',None)
        result = MongoModel.__set_cache__(self, user)
        if result:
            return self.cache.expire(user[self.pk],self.expire)
        return False
    
    def commit(self):
        if not self.user:
            self.lasterror = 'No user infomation.'
            return False
        return self.setuser(**self.user)    
    
    def getuser(self,uid):
        return self.get(_id=uid)
    
    def setuser(self,**user):
        if not user.has_key('passwd') or not user.has_key('uid'):
            self.lasterror = 'No user passwd or no user uid.at UserModel:setuser.'
            return False
        user[self.pk]  = _id = user.pop('uid')
        user['passwd'] = self.__cryptpasswd__(_id, user['passwd'])
        result = self.save(**user)
        if not result:
            self.lasterror = 'The uid is sigined.'
        self.db.ensure_index([('_id',pymongo.DESCENDING)] ,unique = True)
#        if not SearchEngine(*[_id,]*3).insert():
#            self.lasterror = 'index user \'%s\' fail'%_id
        return result
        
    def __cryptpasswd__(self,_id,passwd):
        passwd = '%s<:>%s' % (_id, passwd)
        return hashlib.md5(hashlib.md5(passwd).hexdigest()).hexdigest()
    
    def login(self,uid,passwd):
        passwd = self.__cryptpasswd__(uid, passwd)
        where = { self.pk:uid , 'passwd':passwd}
        return self.db.find(where).count() == 1
    
    def changepasswd(self,uid,oldpasswd,newpasswd):
        if self.login(uid, oldpasswd):
            passwd = self.__cryptpasswd__(uid, newpasswd)
            result = self.db.update({self.pk:uid},{'$set':{'passwd':passwd}},safe=True)
            return result['updatedExisting']
        self.lasterror = 'User oldpasswd error.at UserModel:changepasswd'
        return False
            
    def changeuser(self,uid,**user):
        spec = { self.pk:uid }
        return self.update(spec,user)
    
    def search(self,s,skip=0,limit=10):
        result = SearchEngine().search(s,skip=skip,limit=limit)
        return filter(lambda _i:not not _i,[self.getuser(r) for r in result])
    
    def addquestion(self,uid,qid):
        where = { self.pk : uid}
        result = self.db.update(where,{'$push':{'questions':qid}},safe=True)
        self.cache.rpush(self.__question_key__(uid),qid)
        return result['updatedExisting']
    
    def getquestions(self,uid,skip=0,limit=10):
        data = self.cache.lrange(self.__question_key__(uid),skip,limit)
        if not data:
            user = self.getuser(uid)
            data = user.get('questions',[])
            for i in data:
                self.cache.rpush(self.__question_key__(uid),i)
        return data
    
    def addanswer(self,uid,qid,answer):
        where = { self.pk:uid }
        content = cPickle.dumps({'qid':qid,'answer':answer})
        result = self.db.update(where,{'$push':{'answers':{'qid':qid,'answer':answer}}} , safe=True)
        self.cache.rpush(self.__answer_key__(uid),content)
        return result['updatedExisting']
    
    def getanswers(self,uid,skip=0,limit=10):
        data = self.cache.lrange(self.__answer_key__(uid),skip,limit)
        if not data:
            user = self.getuser(uid)
            data = user.get('answers',[])
            for i in data:
                self.cache.rpush(self.__answer_key__(uid),cPickle.dumps(i))
        return [cPickle.loads(d) for d in data]
        

if __name__ == '__main__':
    with app.test_request_context():
#        print getuseranswers('alan.yang@live.com', 0, 10)
#        user = UserModel(uid = 'lo1veida@live.com' , passwd = '111' , nick = 'love')
#        print user.commit()
#        print user.getlasterror()
        print user.setuser({'uid':'knift1128@gmail.com' , 'passwd':'111','nick':'love'})
#        print user.login('knift1128@gmail.com', '222')
#        print user.changeuser('knift1128@gmail.com' ,nick='ida')
#        print user.changepasswd('knift1128@gmail.com', '111', '222')
#    print setuser(_id='alan.yang@live.com', passwd='111', safe=True)
#    print __cryptpasswd('aaa','aaa')
#    print changeuser('alanyang54@gmail.com',nick='ida')
#    print getuser('alanyang54@gmail.com')
#    print login('alan.yang@live.com' , '111')
#    print changepasswd('alanyang54@gmail.com', '111', '222')
#    print changeuser('alanyang54@gmail.com', site='http://freeasker.com')
    
    
    
    
    
    
    
    
    
    
    
